#if !BOOST_PP_IS_ITERATING
#  ifndef BOOST__THREAD__DETAILS__UNILOCK_INTERFACE_WRAPPER_HPP
#    define BOOST__THREAD__DETAILS__UNILOCK_INTERFACE_WRAPPER_HPP

// Copyright (C) 2004-2009
// Alex Turbov, Igor Veresov
//
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#    include <boost/thread/details/unilock_config.hpp>

#    include <boost/call_traits.hpp>
#    include <boost/mpl/apply.hpp>
#    include <boost/fusion/include/at_c.hpp>
#    include <boost/fusion/include/size.hpp>
#    include <boost/preprocessor/cat.hpp>
#    include <boost/preprocessor/comma_if.hpp>
#    include <boost/preprocessor/enum_params.hpp>
#    include <boost/preprocessor/repetition/enum_binary_params.hpp>
#    include <boost/preprocessor/iterate.hpp>
#    include <boost/preprocessor/repeat.hpp>

namespace boost { namespace details {

template <int Arity>
struct lock_interface_wrapper;

template <int Arity>
struct unlock_interface_wrapper;


struct lock_interface_chooser
{
    template <typename Derived>
    struct apply : public mpl::apply<
        lock_interface_wrapper<
            fusion::result_of::size<
                typename Derived::lock_params_type
              >::type::value
          >
      , Derived
      >::type
    {};
};

struct unlock_interface_chooser
{
    template <typename Derived>
    struct apply : public mpl::apply<
        unlock_interface_wrapper<
            fusion::result_of::size<
                typename Derived::unlock_params_type
              >::type::value
          >
      , Derived
      >::type
    {};
};

}}                                                         // namespace details, boost

#    define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_MAX_LOCK_ARGS, "boost/thread/details/unilock_interface_wrapper.hpp"))
#    include BOOST_PP_ITERATE()

#  endif                                                   // BOOST__THREAD__DETAILS__UNILOCK_INTERFACE_WRAPPER_HPP

#else                                                      // BOOST_PP_IS_ITERATING
#  define N BOOST_PP_ITERATION()

#  define LOCK_ARGS(z, n, text) \
    BOOST_PP_COMMA_IF(n) typename fusion::result_of::at_c<text, n>::type BOOST_PP_CAT(p,n)

namespace boost { namespace details {

template <>
struct lock_interface_wrapper<N>
{
    template <typename Derived>
    struct apply
    {
       struct type
        {
            typedef typename Derived::lock_params_type lock_params_type;
            void lock(BOOST_PP_REPEAT(N, LOCK_ARGS, lock_params_type))
            {
                static_cast<Derived* const>(this)->lock_(
                   lock_params_type(BOOST_PP_ENUM_PARAMS(N, p))
                );
            }
            bool try_lock(BOOST_PP_REPEAT(N, LOCK_ARGS, lock_params_type))
            {
                return static_cast<Derived* const>(this)->try_lock_(
                    lock_params_type(BOOST_PP_ENUM_PARAMS(N, p))
                );
            }
        };
    };
};

template <>
struct unlock_interface_wrapper<N>
{
    template <typename Derived>
    struct apply
    {
        struct type
        {
            typedef typename Derived::lock_params_type unlock_params_type;
            void unlock(BOOST_PP_REPEAT(N, LOCK_ARGS, unlock_params_type))
            {
                static_cast<Derived* const>(this)->unlock_(
                    unlock_params_type(BOOST_PP_ENUM_PARAMS(N, p))
                );
            }
        };
    };
};

}}                                                         // namespace details, boost

#  undef LOCK_ARGS
#  undef N
#endif                                                     // BOOST_PP_IS_ITERATING
